package com.hulman.oms.service;

import com.hulman.oms.bean.Result;
import com.hulman.oms.bean.ScadaReport;
import com.hulman.oms.dao.ScadaReportDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.SqlExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * @Author: maxwellens
 */
@Service
@Slf4j
public class ScadaReportService
{
    @Autowired
    private ScadaReportDao scadaReportDao;
    @Autowired
    private DataSource dataSource;

    public List<ScadaReport> findScadaReports(Map<String, Object> map)
    {
        return scadaReportDao.findScadaReports(map);
    }

    public Integer findScadaReportsCount(Map<String, Object> map)
    {
        return scadaReportDao.findScadaReportsCount(map);
    }

    public Result findScadaReportsResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = scadaReportDao.findScadaReportsCount(map);
        List<ScadaReport> data = scadaReportDao.findScadaReports(map);
        return new Result(data, count);
    }

    public ScadaReport findScadaReportById(Integer id)
    {
        return scadaReportDao.findScadaReportById(id);
    }

    public void saveScadaReport(ScadaReport scadaReport)
    {
        if (scadaReport.getId() != null && scadaReport.getId() != 0)
        {
            scadaReportDao.updateScadaReport(scadaReport);
        } else
        {
            scadaReportDao.insertScadaReport(scadaReport);
        }
    }

    public void deleteScadaReportById(Integer id)
    {
        scadaReportDao.deleteScadaReportById(id);
    }

    public void deleteScadaReports(int[] ids)
    {
        scadaReportDao.deleteScadaReports(ids);
    }

    public List<Map<String, Object>> execute(String identifier) throws SQLException
    {
        ScadaReport scadaReport = scadaReportDao.findScadaReportByIdentifier(identifier);
        if (scadaReport == null)
        {
            throw new IoTException("ScadaReport " + identifier + " not found");
        }
        try (Connection connection = dataSource.getConnection())
        {
            SqlExecutor sqlExecutor = new SqlExecutor(connection);
            List<Map<String, Object>> data = sqlExecutor.selectAll(scadaReport.getSql());
            return data;
        }
    }

    public List<Map<String, Object>> execute(String identifier, Map<String, Object> params) throws SQLException
    {
        ScadaReport scadaReport = scadaReportDao.findScadaReportByIdentifier(identifier);
        if (scadaReport == null)
        {
            throw new IoTException("ScadaReport " + identifier + " not found");
        }
        String sql = scadaReport.getSql();
        try (Connection connection = dataSource.getConnection())
        {
            SqlExecutor sqlExecutor = new SqlExecutor(connection);
            for (Map.Entry<String, Object> entry : params.entrySet())
            {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof String)
                {
                    sql = sql.replaceAll("#\\{" + key + "}", "'" + value + "'");
                } else
                {
                    sql = sql.replaceAll("#\\{" + key + "}", value.toString());
                }
            }
            List<Map<String, Object>> data = sqlExecutor.selectAll(sql);
            return data;
        }
    }
}
